require 'pdf/writer'
require 'pdf/simpletable'

class JobsController < ApplicationController
  include Security::Session::Access
  include Utils::Url
  include Utils::Text

  def list
    if user? && current_user.access_job_management?
      @jobs = Job.find(:all)
    else
      @jobs = Job.find(:all, :conditions => ["enabled = true and period_start <= ? and  ? <= period_end",Time.now.beginning_of_day,Time.now.beginning_of_day])
    end
  end

  def create
    case request.method
    when :post
      if params[:commit] == "Cancel"
        redirect_to(:action => "list")
        return
      end
      params[:job].delete(:id)
      create_job_from_params
      @job.updated_by = current_updater_id
      if @job.save
        flash[:notice] = "Job successfully created"
        redirect_to(:action => "show", :id => @job.id)
      end
    else
      @job = Job.new
      if id_param
        j = Job.find(id_param)
        @job = j.copy
      else
        @job.set_defaults
      end
      @job.period_start = Time.now
      @job.period_end = Time.now.next_week
    end
  end

  def show
    @job = Job.find(id_param)
  end

  def update
    case request.method
    when :post
      if params[:commit] == "Cancel"
        redirect_to(:action => "list")
        return
      end
      @job = Job.find(params[:job][:id])
      params[:job].delete(:id)
      update_job_from_params
      @job.updated_by = current_updater_id
      if @job.save
        flash[:notice] = "Job successfully updated"
        redirect_to(:action => "show", :id => @job.id)
      end
    else
      @job = Job.find(id_param)
    end
  end

  def disable
    @job = Job.find(id_param)
    @job.enabled = false
    @job.save
    redirect_to(:action => "list")
  end

  def enable
    @job = Job.find(id_param)
    @job.enabled = true
    @job.save
    redirect_to(:action => "list")
  end

  def view_pdf
    @job = Job.find(id_param)
    pdf = get_pdf_data
    send_data(pdf.render, :filename => "#{@job.title}.pdf", :type => "application/pdf")
  end

  private
    def create_job_from_params
      @job = Job.new(params[:job])
    rescue ActiveRecord::MultiparameterAssignmentErrors => e
      e.errors.each do |err|
        params[:job].each do |key,value|
           @job.errors.add(key,"invalid date entered") if key =~ /~#{err.attribute}/
        end 
      end
      @job = Job.new(params[:job])
    end

    def update_job_from_params
      @job.attributes = params[:job]
    rescue ActiveRecord::MultiparameterAssignmentErrors => e
      e.errors.each do |err|
        params[:job].each do |key,value|
           @job.errors.add(key,"invalid date entered") if key =~ /~#{err.attribute}/
        end 
      end
      @job.attributes = params[:job]
    end

    def get_pdf_data
      pdf = PDF::Writer.new
      configure_pdf(pdf)
      write_pdf_data(pdf)
      pdf
    end

    def configure_pdf(pdf)
      pdf.select_font("Times-Bold")
      pdf.bottom_margin=48
      create_title(pdf)
      setup_footer(pdf)
    end

    def create_title(pdf)
      pdf.info.title = @job.title
      pdf.fill_color  Color::RGB::DarkBlue
      pdf.text(Easel::COMPANYNAME, :font_size => 22, :justification => :right)
    end

    def setup_footer(pdf)
      pdf.open_object do |footer|
        pdf.save_state
        pdf.stroke_color! Color::RGB::DarkBlue
        pdf.fill_color! Color::RGB::DarkBlue
        pdf.stroke_style! PDF::Writer::StrokeStyle::DEFAULT
        s = 8
        t = @job.footer
        x = pdf.left_margin
        y = pdf.absolute_bottom_margin
        rest = pdf.add_text_wrap(x, y , 450, t, s)
        rest = pdf.add_text_wrap(x, y - (s * 1.01) , 450, rest, s)
        rest = pdf.add_text_wrap(x, y - (s * 2.01) , 450, rest, s)
        rest = pdf.add_text_wrap(x, y - (s * 3.01) , 450, rest, s)
        x = pdf.absolute_left_margin
        w = pdf.absolute_right_margin
        y += (pdf.font_height(s) * 1.01)
        pdf.line(x, y, w, y).stroke
        pdf.restore_state
        pdf.close_object
        pdf.add_object(footer, :all_pages)
      end
    end

    def write_pdf_data(pdf)
      create_job_info(pdf)
      write_paragraph(pdf,"Purpose of Position",@job.description) 
      write_bullets(pdf,"Essential Functions",@job.essential_functions, Job::ESSENTIAL_NOTE) 
      write_bullets(pdf,"Non-Essential Functions",@job.non_essential_functions, Job::NON_ESSENTIAL_NOTE)
      write_bullets(pdf,"Success Factors",@job.success_factors)
      write_bullets(pdf,"Knowledge, Skills and Abilities Required to Successfully Perform Position",@job.required_list)
      write_paragraph(pdf,"Physical Demands",@job.physical_demands)
      write_paragraph(pdf,"How to respond",@job.how_to_respond)
      write_paragraph(pdf,"Notice",@job.notice)
    end

    def create_job_info(pdf)
      draw_line(pdf)
      pdf.stroke_color Color::RGB::DarkBlue
      pdf.y -= 10
      pdf.text("<c:uline>O</c:uline>pen <c:uline>P</c:uline>osition for <c:uline>T</c:uline>ransfer",:font_size => 18,:justification => :left)
      pdf.y -= 8
      table = PDF::SimpleTable.new
      table.show_headings = false
      table.show_lines = :none
      table.shade_rows = :none
      table.width = 300
      orig_margin = pdf.left_margin
      pdf.left_margin = 200
      table.position = :left
      table.font_size = 12
      table.column_order = ["label", "val"]
      table.columns["label"] = PDF::SimpleTable::Column.new("label"){|col| col.width = 100}
      table.columns["val"] = PDF::SimpleTable::Column.new("val")
      table.data = [
        {"label" => "Title", "val" => @job.title},
        {"label" => "Department", "val" => @job.department},
        {"label" => "Supervisor", "val" => @job.supervisor},
        {"label" => "Location", "val" => @job.location},
        {"label" => "Posting Period", "val" => "#{mmddyyyy(@job.period_start)} - #{mmddyyyy(@job.period_end)}"}
      ]
      pdf.select_font("Times-Roman")
      table.render_on(pdf)
      pdf.left_margin = orig_margin
      draw_line(pdf)
    end

    def write_paragraph(pdf,title,content)
      return if empty_or_nil?(content) || empty_or_nil?(title)
      line_length = 0
      paragraphs = content.split("\n")
      paragraphs.each{|para| line_length += para.split("\. ").length }
      pdf.start_new_page if lines_remaining(pdf) < (line_length)
      write_section_title(pdf,title)
      pdf.text(content,:font_size => 12,:justification => :left)
    end

    def write_bullets(pdf,title,content,note = nil)
      return if empty_or_nil?(content) || empty_or_nil?(title)
      items = content.split("\n")
      pdf.start_new_page if (lines_remaining(pdf) < items.length) && (items.length < 5)
      write_section_title(pdf,title,note)
      new_line(pdf)
      i = 0
      items.each do |item|
        i += 1
        current_lines = 0
        current_lines = 2 if pdf.text_width(item) > 80
        rest = pdf.add_text_wrap(pdf.left_margin + 28,pdf.y,450,"<C:bullet/>#{item}")
        lr = lines_remaining(pdf) 
        if lr <= 4 
          if lr < (items.length - (i + current_lines)) 
            pdf.start_new_page
            write_section_title(pdf,title + " (Cont'd)")
          end
        end
        if rest.length > 0
          new_bullet_line(pdf)
          rest = pdf.add_text_wrap(pdf.left_margin + 38,pdf.y,450,"#{rest}")
        end
        new_bullet_line(pdf)
      end
    end

    def write_section_title(pdf,title,note = nil)
      pdf.fill_color! Color::RGB::DarkBlue
      new_line(pdf)
      pdf.select_font("Times-Bold")
      pdf.text(title,:font_size => 12,:justification => :left)
      unless note.nil?
        new_line(pdf)
        pdf.select_font("Times-Italic")
        pdf.text(note,:font_size => 10,:justification => :left)
      end
      pdf.font_size = 12
      pdf.fill_color! Color::RGB::Black
      pdf.select_font("Times-Roman")
      new_line(pdf)
    end

    def new_bullet_line(pdf)
      pdf.y -= 18 
    end

    def new_line(pdf)
      pdf.y -= 12 
    end

    def draw_line(pdf)
      pdf.stroke_color Color::RGB::DarkGrey
      pdf.y -= 16
      pdf.line(pdf.absolute_left_margin, pdf.y, pdf.absolute_right_margin,pdf.y).stroke
    end

    def lines_remaining(pdf)
      #subtract the footer
      pdf.lines_remaining - 4
    end

end
